package com.dbflow5.query;

import com.dbflow5.StringUtils;
import com.dbflow5.query.property.IProperty;
import com.dbflow5.query.property.Property;
import com.dbflow5.sql.Query;
import com.dbflow5.sql.QueryCloneable;
import ohos.agp.utils.TextTool;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * Description: A SQL SELECT statement generator. It generates the SELECT part of the statement.
 */
public class Select implements Query, QueryCloneable<Select> {

    private final QualifierType Distinct = new QualifierType("DISTINCT");
    private final QualifierType All = new QualifierType("ALL");
    private final QualifierType None = new QualifierType("NONE");

    public Select(IProperty<?>... properties){
        init(properties);
    }

    /**
     * The select qualifier to append to the SELECT statement
     */
    private QualifierType selectQualifier = None;

    private final List<IProperty<?>> propertyList = new ArrayList<>();

    @Override
    public String getQuery() {
        StringBuilder queryBuilder = new StringBuilder("SELECT ");
        if(TextTool.isEqual(selectQualifier.value, Distinct.value)){
            queryBuilder.append("DISTINCT ");
        }else if(TextTool.isEqual(selectQualifier.value, All.value)){
            queryBuilder.append("ALL ");
        }
        queryBuilder.append(StringUtils.joinToString(propertyList,", "));
        queryBuilder.append(" ");
        return queryBuilder.toString();
    }

    @Override
    public Select cloneSelf() {
        return new Select(propertyList.toArray(new IProperty[]{}));
    }

    private void init(IProperty<?>... properties) {
        propertyList.addAll(Arrays.asList(properties));
        if (propertyList.isEmpty()) {
            propertyList.add(Property.ALL_PROPERTY);
        }
    }

    /**
     * Passes this statement to the [From]
     *
     * @param table    The model table to run this query on
     * @return the From part of this query
     */
    public <T> From<T> from(Class<T> table){
        return new From<>(this, table, null);
    }

    /**
     * Constructs a [From] with a [ModelQueriable] expression.
     * @param modelQueriable modelQueriable
     * @param <T> T
     * @return the From part of this query
     */
    public <T> From<T> from(ModelQueriable<T> modelQueriable){
        return new From<>(this, modelQueriable.table(), modelQueriable);
    }

    /**
     * appends [.DISTINCT] to the query
     *
     * @return Select
     */
    public Select distinct(){
        return selectQualifier(Distinct);
    }

    @Override
    public String toString() {
        return getQuery();
    }

    /**
     * Helper method to pick the correct qualifier for a SELECT query
     *
     * @param qualifier Can be [.ALL], [.NONE], or [.DISTINCT]
     * @return Select
     */
    private Select selectQualifier(QualifierType qualifier) {
        selectQualifier = qualifier;
        return this;
    }


    private static class QualifierType{
        private String value;

        public QualifierType(String value){
            this.value = value;
        }

        public String getValue() {
            return value;
        }

        public void setValue(String value) {
            this.value = value;
        }
    }

    public static Select select(){
        return SQLite.select();
    }
}

